package com.yuntian;


import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Component
@EnableScheduling
public class SyncYunTianService {


   /* @Scheduled(cron = "0 0 0/1 * * ?")*/
    public void syncDataTask() {
        log.info("开始同步数据");
        log.info("同步数据完成");
    }


    public void syncDept() {
        // 获取单位
        JSONArray dws = this.getOrgAccounts();
        if (dws == null || dws.isEmpty()) {
            return;
        }
        // 所有的平铺的单位信息List<JSONObject>
        List<JSONObject> list = CollUtil.newArrayList();
        // 遍历单位
        for (Object dw : dws) {
            JSONObject d = JSONUtil.parseObj(dw);
            Long id = d.getLong("id");
            List<JSONObject> allOrgAccounts = this.getAllOrgAccounts(id);
            list.addAll(allOrgAccounts);
        }


    }


    private static final String ORG_ACCOUNTS_URL = "http://oa.yth.cn/seeyon/rest/orgAccounts";

    /**
     * 获取单位只返回了2层 大概十几个
     *
     * @return 接口返回的JSON对象，如果请求失败则返回null
     */
    public static JSONArray getOrgAccounts() {
        try (HttpResponse response = HttpRequest.get(ORG_ACCOUNTS_URL)
                // 添加Token参数到URL
                .form("token", new TokenCacheManager().getToken())
                // 设置User-Agent头
                .header("User-Agent", "Apifox/1.0.0 (https://apifox.com)")
                // 设置超时时间为10秒
                .timeout(10000)
                .execute()) {

            // 检查响应状态
            if (response.isOk()) {
                // 解析响应为JSON对象
                return JSONUtil.parseArray(response.body());
            } else {
                System.err.println("请求组织账户接口失败，状态码：" + response.getStatus());
                System.err.println("响应内容：" + response.body());
                return null;
            }
        } catch (Exception e) {
            System.err.println("请求组织账户接口发生异常：" + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }


    // 递归单位信息接口基础URL
    private static final String ORG_ACCOUNT_BASE_URL = "http://oa.yth.cn/seeyon/rest/orgAccounts/";
    /**
     * 递归获取所有单位信息
     *
     * @param rootOrgId 根单位ID
     * @return 所有单位信息的列表
     */
    public static List<JSONObject> getAllOrgAccounts(Long rootOrgId) {
        List<JSONObject> allOrgs = new ArrayList<>();
        // 从根单位开始递归
        recursiveFetch(rootOrgId, allOrgs);
        return allOrgs;
    }

    /**
     * 递归获取单位信息的核心方法
     *
     * @param orgId      当前要获取的单位ID
     * @param resultList 存储所有单位信息的列表
     */
    public static void recursiveFetch(Long orgId, List<JSONObject> resultList) {
        // 获取当前单位信息（接口返回的是数组）
        JSONArray orgArray = getOrgAccountArray(orgId);
        // 如果返回数组为null或为空，停止递归
        if (orgArray == null || orgArray.isEmpty()) {
            return;
        }
        // 处理数组中的每个单位对象
        for (Object obj : orgArray) {
            if (obj instanceof JSONObject) {
                JSONObject orgObj = (JSONObject) obj;
                // 将当前单位信息加入结果列表
                resultList.add(orgObj);
                // 获取当前单位的id，用于查询下一级
                Long childOrgId = orgObj.getLong("id");
                if (childOrgId != null) {
                    // 递归查询子单位
                    recursiveFetch(childOrgId, resultList);
                }
            }
        }
    }

    /**
     * 基础方法：根据单位ID获取单位信息数组
     *
     * @param orgId 单位ID
     * @return 单位信息JSON数组
     */
    public static JSONArray getOrgAccountArray(Long orgId ) {
        // 构建完整请求URL
        String url = ORG_ACCOUNT_BASE_URL + orgId;

        try (HttpResponse response = HttpRequest.get(url)
                .form("token", new TokenCacheManager().getToken())
                .header("User-Agent", "Apifox/1.0.0 (https://apifox.com)")
                .timeout(10000)
                .execute()) {

            if (response.isOk()) {
                // 解析响应为JSON数组（根据接口返回调整）
                return JSONUtil.parseArray(response.body());
            } else {
                System.err.println("获取单位ID为" + orgId + "的信息失败，状态码：" + response.getStatus());
                System.err.println("响应内容：" + response.body());
                return null;
            }
        } catch (Exception e) {
            System.err.println("获取单位ID为" + orgId + "的信息时发生异常：" + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }


    /**
     * token 缓存管理器
     */
    public static class TokenCacheManager {
        // Token请求URL
        private static final String TOKEN_URL = "https://oa.yth.cn/seeyon/rest/token";
        // 缓存有效期5分钟(比实际失效时间短，提前刷新)
        private static final long CACHE_EXPIRE_MINUTES = 5;
        // Hutool缓存实例
        private static final Cache<String, String> tokenCache = CacheUtil.newTimedCache(CACHE_EXPIRE_MINUTES * 60 * 1000);
        private String userName = "baiduai";
        private String password = "3e31a41d-936b-4a0a-b1cc-dcd68fbaf49a";

        /**
         * 获取Token(优先从缓存获取，失效则重新请求)
         */
        public String getToken() {
            // 尝试从缓存获取
            String token = tokenCache.get("OA_TOKEN");

            // 缓存不存在或已失效，重新获取
            if (token == null) {
                synchronized (TokenCacheManager.class) {
                    // 双重检查，避免并发重复请求
                    token = tokenCache.get("OA_TOKEN");
                    if (token == null) {
                        token = fetchNewToken();
                        if (token != null) {
                            // 存入缓存
                            tokenCache.put("OA_TOKEN", token);
                            System.out.println("Token已更新并缓存，有效期" + CACHE_EXPIRE_MINUTES + "分钟");
                        }
                    }
                }
            }
            return token;
        }

        /**
         * 从接口获取新的Token
         */
        private String fetchNewToken() {
            try {
                // 构建请求体
                JSONObject requestBody = JSONUtil.createObj()
                        .set("userName", userName)
                        .set("password", password);

                // 发送POST请求
                try (HttpResponse response = HttpRequest.post(TOKEN_URL)
                        .header("Content-Type", "application/json")
                        .body(requestBody.toString())
                        .timeout(5000) // 5秒超时
                        .execute()) {

                    if (response.isOk()) {
                        JSONObject result = JSONUtil.parseObj(response.body());
                        // 根据实际接口返回的Token字段名调整
                        return result.getStr("id");
                    } else {
                        System.err.println("获取Token失败，状态码：" + response.getStatus());
                        System.err.println("响应内容：" + response.body());
                        return null;
                    }
                }
            } catch (Exception e) {
                System.err.println("获取Token异常：" + e.getMessage());
                e.printStackTrace();
                return null;
            }
        }


        public static void main(String[] args) {


        }
    }







}
